
package com.feib.soeasy.dao.hibernate;

import java.util.Date;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.feib.soeasy.dao.UserActionLogDao;
import com.feib.soeasy.model.UserActionLog;
import com.feib.soeasy.pagination.PaginatedList;
import com.feib.soeasy.util.DateUtil;


/**
 * @title (#)UserActionLogHibernateDao.java<br>
 * @description <br>
 * @author Jimmy Liu<br>
 * @version 1.0.0 2010/11/25
 * @copyright Far Eastern International Bank Copyright (c) 2010<br>
 * @2010/12/6 create by Jimmy Liu<br>
 */
@Repository("userActionLogDao")
public class UserActionLogHibernateDao extends BaseHibernateDao<UserActionLog, Long> implements UserActionLogDao {

    /* (non-Javadoc)
     * @see com.feib.soeasy.dao.UserActionLogDao#findByUserActionLog(com.feib.soeasy.model.UserActionLog, java.util.Date, java.util.Date, com.feib.soeasy.pagination.PaginatedList)
     */
    @SuppressWarnings("unchecked")
    @Override
    public PaginatedList<UserActionLog> findByUserActionLog(UserActionLog userActionLog, Date inDateFrom, Date inDateTo, List<String> actionBeans,PaginatedList<UserActionLog> paginationConfig) {
        PaginatedList<UserActionLog> result = new PaginatedList<UserActionLog>();
        result.setPageSize(paginationConfig.getPageSize());
        result.setPageNumber(paginationConfig.getPageNumber());
        result.setSortCriterion(paginationConfig.getSortCriterion());
        result.setSortDirection(paginationConfig.getSortDirection());
        
        result.setFullListSize(super.countByDetachedCriteria(createDetachedCriteriaByUserActionLog(userActionLog, inDateFrom, inDateTo, actionBeans)));
        
        // 筆數大於0
        if (0 < result.getFullListSize())
        {
            DetachedCriteria criteria = createDetachedCriteriaByUserActionLog(userActionLog, inDateFrom, inDateTo, actionBeans);

            criteria.addOrder(Order.desc("inDateTime"));
            criteria.addOrder(Order.asc("groupNo"));
            criteria.addOrder(Order.asc("usernName"));

            int maxResults = result.getPageSize(); //the maximum number of results
            int firstResult = result.getFirstIndexForCurrentPage();  //the first result to retrieve, numbered from 0
            result.setPaginatedList(this.getHibernateTemplate().findByCriteria(criteria, firstResult, maxResults));
        }

        return result;
    }

    /**
     * @param userActionLog
     * @param inDateFrom
     * @param inDateTo
     * @return
     */
    private DetachedCriteria createDetachedCriteriaByUserActionLog(UserActionLog entity, Date inDateFrom, Date inDateTo, List<String> actionBeans) {
        DetachedCriteria criteria = DetachedCriteria.forClass(this.getPersistentClass());
        criteria.setResultTransformer(DetachedCriteria.DISTINCT_ROOT_ENTITY);
        
        if (null != entity)
        {
            Example example = Example.create(entity);
            example.enableLike(MatchMode.START);
            criteria.add(example);
        }
        
        if (null != actionBeans && 0 != actionBeans.size())
        {
            criteria.add(Restrictions.in("actionBean", actionBeans));
        }

        // 交易日期
        // 有起迄
        if (null != inDateFrom && null != inDateTo)
        {
            criteria.add(Restrictions.between("inDateTime",inDateFrom, inDateTo));
        }
        else if (null != inDateFrom) // 只有起
        {
            criteria.add(Restrictions.ge("inDateTime", inDateFrom));
        }
        else if (null != inDateTo) // 只有迄
        {
            criteria.add(Restrictions.le("inDateTime", inDateTo));
        }
        else if (null != entity && null != entity.getInDateTime())//單一日期
        {
            Date from = DateUtil.getInstance().getBeginOfDateTime(entity.getInDateTime());
            Date to = DateUtil.getInstance().getEndOfDateTime(entity.getInDateTime());
            criteria.add(Restrictions.between("inDateTime", from, to));
        }
        
        return criteria;
    }

}
